package com.txzt.gaea.provide.service.impl;


import com.txzt.base.core.RtnInfo;
import com.txzt.gaea.common.base.service.impl.BaseServiceImpl;
import com.txzt.gaea.common.core.base.context.AdminUserContext;
import com.txzt.gaea.common.page.PageInfoBT;
import com.txzt.gaea.provide.dto.InformationDeliveryAddDTO;
import com.txzt.gaea.provide.dto.InformationDeliveryQueryDTO;
import com.txzt.gaea.provide.dto.InformationDeliveryUpdateDTO;
import com.txzt.gaea.provide.enums.InformationDeliveryTypeEnum;
import com.txzt.gaea.provide.enums.SecrecyLevelEnum;
import com.txzt.gaea.provide.model.FileInfo;
import com.txzt.gaea.provide.model.InformationDelivery;
import com.txzt.gaea.provide.model.InformationTypeInfo;
import com.txzt.gaea.provide.service.FileInfoService;
import com.txzt.gaea.provide.service.InformationDeliveryService;
import com.txzt.gaea.provide.service.InformationTypeInfoService;
import com.txzt.gaea.provide.service.biz.AdminUserApiService;
import com.txzt.gaea.provide.utils.BeanConvertUtils;
import com.txzt.gaea.provide.vo.InformationDeliveryVO;
import com.txzt.gaea.provide.vo.SpecifyUserVO;
import com.txzt.gaea.vo.AdminUserVO;
import com.txzt.gaea.vo.UserDetailVO;
import io.lettuce.core.internal.LettuceLists;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.math.NumberUtils;
import org.beetl.sql.core.engine.PageQuery;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.*;


@Service
@Log4j2
public class InformationDeliveryServiceImpl extends BaseServiceImpl<InformationDelivery> implements InformationDeliveryService {


    @Autowired
    private AdminUserApiService adminUserApiService;

    @Autowired
    private FileInfoService fileInfoService;

    @Autowired
    private InformationTypeInfoService informationTypeInfoService;

    @Value("${roleConfig.ipaddr}")
    String ipaddr;

    @Override
    public RtnInfo<PageInfoBT<InformationDeliveryVO>> list(InformationDeliveryQueryDTO dto) throws Exception {
        AdminUserVO adminUserVO = AdminUserContext.getUser();
        if (null == adminUserVO) {
            return RtnInfo.error(500, "当前用户已过期，请重新登录。");
        }
        if (dto.getDataSource() == 1){
            boolean isAdminUser = adminUserApiService.checkAdminUser(adminUserVO);
            if (!isAdminUser){
                dto.setDeliveryUserId(adminUserVO.getId());
            }
        }
        PageQuery<InformationDelivery> pageQuery = new PageQuery<>(dto.getPageNumber(), dto.getPageSize(), dto);
        PageQuery<InformationDelivery> result = this.sqlManager.pageQuery("informationDelivery.queryByCondition", InformationDelivery.class, pageQuery);
        //为空直接返回
        if (CollectionUtils.isEmpty(result.getList())) {
            return RtnInfo.success(new PageInfoBT(result));
        }
        List<InformationDeliveryVO> vos = new ArrayList<>();
        List<Long> userIds = new ArrayList<>();
        for (InformationDelivery informationDelivery : result.getList()) {
            InformationDeliveryVO vo = BeanConvertUtils.convertTo(informationDelivery, InformationDeliveryVO::new, (s, t) -> {
                //取附件名称，扩展以后会有多个附件
                String fileIds = informationDelivery.getFileInfoIds();
                t.setFileName(getFileName(fileIds));
                t.setFileUrl(getFileUrl(fileIds));
                t.setServerFileName(getServerFileName(t.getFileUrl()));
                InformationTypeInfo informationTypeInfo = informationTypeInfoService.selectById(s.getInformationType());
                if (null != informationTypeInfo){
                    t.setInformationTypeName(informationTypeInfo.getInformationTypeName());
                }

                t.setSecrecyLevelName(SecrecyLevelEnum.getByValue(s.getSecrecyLevel()).getCode());
            });

            //TODO 如果当前用户不是指定用户,则不显示，单个文件上传
            String userIdSS = informationDelivery.getUserIds();
            if(org.apache.commons.lang3.StringUtils.isNotEmpty(userIdSS)){
                String[] userIdSSS = org.apache.commons.lang3.StringUtils.split(userIdSS, ";");
                List<String> userIdSSSS = Arrays.asList(userIdSSS);
                //如果当前用户不在指定用户上则直接返回
                if(!userIdSSSS.contains(new StringBuilder(AdminUserContext.getUser().getName()).append("/").append(String.valueOf(AdminUserContext.getUser().getId())).toString())){
                    continue;
                }
            }

            userIds.add(informationDelivery.getDeliveryUserId());
            vos.add(vo);
        }
        Map<Long, UserDetailVO> userDetailMap = adminUserApiService.getUserDetailVos(userIds);
        if (!CollectionUtils.isEmpty(userDetailMap)) {
            for (InformationDeliveryVO vo : vos) {
                if (!userDetailMap.containsKey(vo.getDeliveryUserId())) {
                    log.error("门户没有查到发布者ID, 文件ID：{}， 发布者ID:{}", vo.getId(), vo.getDeliveryUserId());
                    continue;
                }
                UserDetailVO userDetailVO = userDetailMap.get(vo.getDeliveryUserId());
                vo.setDeliveryUserName(userDetailVO.getName());
                vo.setBelongDeptName(userDetailVO.getDeptVO().getSimplename());
                vo.setGaeaJumpUrl(ipaddr + vo.getServerFileName());

                String specifyUsers = vo.getUserIds();
                if(org.apache.commons.lang3.StringUtils.isNotEmpty(specifyUsers)){
                    String[] specifyUsersS = org.apache.commons.lang3.StringUtils.split(specifyUsers, ";");

                    List<SpecifyUserVO> specifyUserVOList = new ArrayList<>();
                    for(String s: specifyUsersS){
                        String[] ss = StringUtils.split(s, "/");
                        SpecifyUserVO specifyUserVO = new SpecifyUserVO();
                        specifyUserVO.setId(Long.parseLong(ss[1]));
                        specifyUserVO.setName(ss[0]);
                        specifyUserVOList.add(specifyUserVO);
                    }
                    vo.setSpecifyUserVOList(specifyUserVOList);
                }
            }
        }
        result.setList(vos);

        //重构
        PageInfoBT<InformationDeliveryVO> re = new PageInfoBT(result);
        rebuild(re);
        return RtnInfo.success(re);
    }

    /**
     * 重构
     *
     * @param re
     */
    private void rebuild(PageInfoBT<InformationDeliveryVO> re){
        List list = re.getRows();
        if(CollectionUtils.isEmpty(list)){
            re.setTotal(0);
            return;
        }
        re.setTotal(list.size());
    }


    private String getServerFileName(String fileUrl) {
        if (StringUtils.isBlank(fileUrl)){
            return "";
        }
        String[] urls =  fileUrl.split("/");
        if (urls.length <= 1){
            return fileUrl;
        }
        return urls[urls.length -1];
    }


    @Override
    public RtnInfo add(InformationDeliveryAddDTO dto) throws Exception {
        AdminUserVO adminUserVO = AdminUserContext.getUser();
        if (null == adminUserVO) {
            return RtnInfo.error(500, "当前用户已过期，请重新登录。");
        }
        Date time = new Date();
        InformationDelivery informationDelivery = BeanConvertUtils.convertTo(dto, InformationDelivery::new, (s, t) -> {
            t.setCreateTime(time);
            t.setCreateBy(adminUserVO.getId());
            t.setIsDelete(0);
            if (null == s.getDeliveryUserId() || 0 == s.getDeliveryUserId()) {
                t.setDeliveryUserId(adminUserVO.getId());
            }
            if (null == s.getBelongDept() || 0 == s.getBelongDept()) {
                t.setBelongDept(adminUserVO.getDeptid());
            }
            if (StringUtils.isBlank(s.getDeliveryTime())) {
                t.setDeliveryTime(time);
            }
            //如果不为空，则添加当前人员
            if(org.apache.commons.lang3.StringUtils.isNotEmpty(s.getUserIds())){
                t.setUserIds(new StringBuilder(s.getUserIds()).append(";").append(adminUserVO.getName()).append("/").append(adminUserVO.getId()).toString());
            }
        });
        int count = this.save(informationDelivery);
        if (count <= 0) {
            return RtnInfo.SERVER_ERROR;
        }
        return RtnInfo.SUCCESS;
    }

    @Override
    public RtnInfo update(InformationDeliveryUpdateDTO dto) throws Exception {
        AdminUserVO adminUserVO = AdminUserContext.getUser();
        if (null == adminUserVO) {
            return RtnInfo.error(500, "当前用户已过期，请重新登录。");
        }
        Date time = new Date();
        InformationDelivery informationDelivery = BeanConvertUtils.convertTo(dto, InformationDelivery::new, (s, t) -> {
            t.setUpdateBy(adminUserVO.getId());
            t.setUpdateTime(time);
            String tttt = new StringBuilder().append(adminUserVO.getName()).append("/").append(adminUserVO.getId()).toString();
            if(org.apache.commons.lang3.StringUtils.isNotEmpty(s.getUserIds()) && s.getUserIds().indexOf(tttt) < 0 ){
                t.setUserIds(new StringBuilder(s.getUserIds()).append(";").append(tttt).toString());
            }
        });
        int count = this.sqlManager.update("informationDelivery.updateInfoById", informationDelivery);
        if (count <= 0) {
            return RtnInfo.SERVER_ERROR;
        }
        return RtnInfo.SUCCESS;
    }

    @Override
    public RtnInfo del(Long id) {
        AdminUserVO adminUserVO = AdminUserContext.getUser();
        if (null == adminUserVO) {
            return RtnInfo.error(500, "当前用户已过期，请重新登录。");
        }
        InformationDelivery informationDelivery = InformationDelivery.builder().id(id).updateBy(adminUserVO.getId()).
                updateTime(new Date()).isDelete(1).build();
        int count = this.sqlManager.update("informationDelivery.updateInfoById", informationDelivery);
        if (count <= 0) {
            log.error("删除数据失败。id:{}", id);
            return RtnInfo.SERVER_ERROR;
        }
        return RtnInfo.SUCCESS;
    }

    @Override
    public RtnInfo<InformationDeliveryVO> detail(Long id) throws Exception {
        InformationDelivery informationDelivery = this.selectById(id);
        InformationDeliveryVO vo = BeanConvertUtils.convertTo(informationDelivery, InformationDeliveryVO::new, (s, t) -> {
            String fileIds = informationDelivery.getFileInfoIds();
            t.setFileName(getFileName(fileIds));
            InformationTypeInfo informationTypeInfo = informationTypeInfoService.selectById(s.getInformationType());
            if (null != informationTypeInfo){
                t.setInformationTypeName(informationTypeInfo.getInformationTypeName());
            }
            t.setSecrecyLevelName(SecrecyLevelEnum.getByValue(s.getSecrecyLevel()).getCode());
            t.setFileUrl(getFileUrl(fileIds));
            t.setServerFileName(getServerFileName(t.getFileUrl()));
        });
        Map<Long, UserDetailVO> userDetailMap = adminUserApiService.getUserDetailVos(LettuceLists.newList(vo.getDeliveryUserId()));
        if (!CollectionUtils.isEmpty(userDetailMap)) {
            if (!userDetailMap.containsKey(vo.getDeliveryUserId())) {
                log.error("门户没有查到发布者ID, 文件ID：{}， 发布者ID:{}", vo.getId(), vo.getDeliveryUserId());
                return RtnInfo.success(vo);
            }
            UserDetailVO userDetailVO = userDetailMap.get(vo.getDeliveryUserId());
            vo.setDeliveryUserName(userDetailVO.getName());
            vo.setBelongDeptName(userDetailVO.getDeptVO().getSimplename());
        }
        return RtnInfo.success(vo);
    }


    private String getFileName(String fileIds) {
        StringBuilder sb = new StringBuilder();
        for (String fileIdStr : fileIds.split(",")) {
            Long fileId = NumberUtils.toLong(fileIdStr);
            if (fileId <= 0) {
                break;
            }
            FileInfo fileInfo = fileInfoService.selectById(fileId);
            if (null != fileInfo) {
                if (StringUtils.isNotBlank(sb.toString())) {
                    sb.append(",");
                }
                sb.append(fileInfo.getFileName());
            }
        }
        return sb.toString();
    }

    private String getFileUrl(String fileIds) {
        StringBuilder sb = new StringBuilder();
        for (String fileIdStr : fileIds.split(",")) {
            Long fileId = NumberUtils.toLong(fileIdStr);
            if (fileId <= 0) {
                break;
            }
            FileInfo fileInfo = fileInfoService.selectById(fileId);
            if (null != fileInfo) {
                if (StringUtils.isNotBlank(sb.toString())) {
                    sb.append(",");
                }
                sb.append(fileInfo.getFileUrl());
            }
        }
        return sb.toString();
    }
}
